iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0
自我挑戰組

新手前端與真實世界的開發 feat.React 與他的夥伴系列 第 13

Day-13 專案演練 - React 拆元件的思路與操作(中)

  • 分享至 

  • xImage
  •  

Day-13 專案演練 - React 拆元件的思路與操作(中)

到了這個階段,我發現一件事情...就是,我在 Day-7 時有提到要輸出報表,然後的這幾天我完全不記得這件事情,所以都沒考慮 XD,好喔,那我想起來了,今天除了繼續拆元件以外,我也會把這個輸出報表的功能考慮進來,來改我的 UI。

抽出整個 header

從 DefaultLayout 整個 header 抽取出來,放到 components。

header.tsx

import React from "react";
import { Outlet, Link } from "react-router-dom";
import Button from "../components/Button";

const Header = () => {
  return (
    <div className="flex justify-between items-center shadow px-[20px] py-[20px]">
      <h1 className="text-[30px] font-medium">
        <Link to="/">MyNote</Link>
      </h1>
      <div>
        <Button className="mr-[8px]">
          <Link to="/dashboard">Dashboard</Link>
        </Button>
        <Button className="mr-[8px]">
          <Link to="/todo">Todos</Link>
        </Button>
      </div>
    </div>
  );
};

export default Header;

接下來是變得相當乾淨的 DefaultLayout.tsx :

其實這樣做有個優點,就是當我需要全站浮動按鈕或者一個暫時的側邊按鈕時,可以在裡面新增,因為全部都包成元件,可以一目了然的知道我整個外框裡面有多出哪些浮動按鈕,我自己常用的是在這裡放進回到頂部的鈕。

import React from "react";
import { Outlet, Link } from "react-router-dom";
import Header from "../components/Header";

const DefaultLayout: React.FC = () => {
  return (
    <>
      <Header />

      <Outlet />
    </>
  );
};

export default DefaultLayout;

增加輸出報表按鈕

好啦,來填這個我忘掉的坑,總之就馬上新增輸出按鈕上去吧!

打開 TodoPage,把這個按鈕加在新增todo按鈕的隔壁,看來我當初預留的空間用上了,而且還有很多空間,可以加好加滿(打算搞死自己吧XD)。

TodoPage.tsx

...
        <section className="flex justify-between"> // 太多層 div 已經開始混亂,所以用 section 包裹
        <div className="flex items-center">
          <svg
            width="32"
            height="32"
            viewBox="0 0 32 32"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
          >
            <rect width="32" height="32" rx="6" fill="#EDF2F7" />
            <path
              d="M23.7918 16.5416H17.5418V22.7916H15.4585V16.5416H9.2085V14.4583H15.4585V8.20831H17.5418V14.4583H23.7918V16.5416Z"
              fill="black"
            />
          </svg>
          <span className="ml-[8px]">新增待辦</span>
        </div>
          <div className="flex items-center">
            <svg
              width="25"
              height="25"
              viewBox="0 0 225 225"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <path
                d="M155.296 84.2473H140.412V37.4432C140.412 32.2948 136.2 28.0824 131.051 28.0824H93.6081C88.4597 28.0824 84.2473 32.2948 84.2473 37.4432V84.2473H69.3636C61.0325 84.2473 56.8201 94.3569 62.7174 100.254L105.684 143.22C109.334 146.871 115.232 146.871 118.882 143.22L161.848 100.254C167.746 94.3569 163.627 84.2473 155.296 84.2473ZM46.8041 177.855C46.8041 183.004 51.0164 187.216 56.1649 187.216H168.495C173.643 187.216 177.855 183.004 177.855 177.855C177.855 172.707 173.643 168.494 168.495 168.494H56.1649C51.0164 168.494 46.8041 172.707 46.8041 177.855Z"
                fill="black"
              />
            </svg>
            <span className="ml-[8px]">下載報表</span>
          </div>
        </section>
...

新增資料夾 features 與使用時機

有時候我會感覺很懶惰,不想把功能跟 UI 拆散的時候,我會將一組 UI 連同它的功能一起放到 features 資料夾。

雖然現在還只有一顆按鈕而已,但之後我會把輸出報表的功能也做進去。

在 features 中加入 ExportButton.tsx :

import React from "react";

const ExportButton = () => {
  return (
    <div className="flex items-center">
      <svg
        width="25"
        height="25"
        viewBox="0 0 225 225"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <path
          d="M155.296 84.2473H140.412V37.4432C140.412 32.2948 136.2 28.0824 131.051 28.0824H93.6081C88.4597 28.0824 84.2473 32.2948 84.2473 37.4432V84.2473H69.3636C61.0325 84.2473 56.8201 94.3569 62.7174 100.254L105.684 143.22C109.334 146.871 115.232 146.871 118.882 143.22L161.848 100.254C167.746 94.3569 163.627 84.2473 155.296 84.2473ZM46.8041 177.855C46.8041 183.004 51.0164 187.216 56.1649 187.216H168.495C173.643 187.216 177.855 183.004 177.855 177.855C177.855 172.707 173.643 168.494 168.495 168.494H56.1649C51.0164 168.494 46.8041 172.707 46.8041 177.855Z"
          fill="black"
        />
      </svg>
      <span className="ml-[8px]">下載報表</span>
    </div>
  );
};

export default ExportButton;

記得再把它引入回 TodoPage.tsx :

...
        <section className="flex justify-between">
          <div className="flex items-center">
            <svg
              width="32"
              height="32"
              viewBox="0 0 32 32"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <rect width="32" height="32" rx="6" fill="#EDF2F7" />
              <path
                d="M23.7918 16.5416H17.5418V22.7916H15.4585V16.5416H9.2085V14.4583H15.4585V8.20831H17.5418V14.4583H23.7918V16.5416Z"
                fill="black"
              />
            </svg>
            <span className="ml-[8px]">新增待辦</span>
          </div>
          <ExportButton />
        </section>
...

新增 DashboardPage


因為 Day-9 與 Day-10 已經做過切版,所以 DashboardPage、HomePage 我就等拆元件的單元結束,直接切好,放上來給大家就行了。

結語

已經處理掉大半的切版工作(擦汗)。

拆開元件是為了要讓它們各司其職(元件就單純呈現樣式,外框就單純的作為容器),但有的時候可以將 UI 跟功能綁在一起,放在 features,這要看我們需要的實際上是哪一種安排,這也沒有一個絕對的作法,可以多多嘗試喔。


上一篇
Day-12 專案演練 - React 拆元件的思路與操作(上)
下一篇
Day-14 專案演練 - React 拆元件的思路與操作(下)
系列文
新手前端與真實世界的開發 feat.React 與他的夥伴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言